/**
 * @file lv_demo_music_main.c
 * LVGL音乐演示 - 主播放界面组件
 */


/*********************
 *      INCLUDE
 *********************/
//导入库
#include <stdio.h>
#include <stdlib.h>
#include <string.h>  // 用于 strcmp 函数
//导入自定义头文件
#include "lv_demo_music_main.h"
#include "lv_demo_music_list.h"
#include "lv_demo_music_font.h"  // 添加字体头文件
#include "lv_demo_music_lyric.h"
#include "mp3_import.h"
#include "setting.h"             // 设置功能头文件
#include "lrc_parser.h"
#include "sport.h"
#include "mp3_player.h"

#include "assets/spectrum_1.h"  // 频谱数据1
#include "assets/spectrum_2.h"  // 频谱数据2
#include "assets/spectrum_3.h"  // 频谱数据3


/*********************
 *      DEFINES
 *********************/
#define INTRO_TIME          2000    // 介绍动画时间(毫秒)
#define BAR_COLOR1          lv_color_hex(0xe9dbfc)  // 频谱条颜色1(浅紫色)
#define BAR_COLOR2          lv_color_hex(0x6f8af6)  // 频谱条颜色2(蓝色)
#define BAR_COLOR3          lv_color_hex(0xffffff)  // 频谱条颜色3(白色)

// 根据屏幕尺寸定义颜色停止点
#if LV_DEMO_MUSIC_LARGE
# define BAR_COLOR1_STOP     160    // 大屏颜色1停止点
# define BAR_COLOR2_STOP     200    // 大屏颜色2停止点
#else
# define BAR_COLOR1_STOP     80     // 小屏颜色1停止点
# define BAR_COLOR2_STOP     100    // 小屏颜色2停止点
#endif
#define BAR_COLOR3_STOP     (2 * LV_HOR_RES / 3)  // 颜色3停止点(基于屏幕宽度)
#define BAR_CNT             20      // 频谱条数量
#define DEG_STEP            (180/BAR_CNT)  // 每个频谱条的角度步长
#define BAND_CNT            4       // 频带数量
#define BAR_PER_BAND_CNT    (BAR_CNT / BAND_CNT)  // 每个频带的频谱条数


//=====第一部分：静态变量======================================================================================================================//

/**********************
 *  STATIC PROTOTYPES
 **********************/

// 界面创建函数
static lv_obj_t * create_cont(lv_obj_t * parent);              // 创建主容器
static void create_wave_images(lv_obj_t * parent);             // 创建波浪图像
static lv_obj_t * create_title_box(lv_obj_t * parent);         // 创建标题框
static lv_obj_t * create_icon_box(lv_obj_t * parent);          // 创建图标框
static lv_obj_t * create_spectrum_obj(lv_obj_t * parent);      // 创建频谱对象
static lv_obj_t * create_ctrl_box(lv_obj_t * parent);          // 创建控制框
static lv_obj_t * create_handle(lv_obj_t * parent);            // 创建手柄
static lv_obj_t * lyric_obj;  // 歌词对象

// 动画和事件回调函数
static void spectrum_anim_cb(void * a, int32_t v);             // 频谱动画回调
static void start_anim_cb(void * a, int32_t v);                // 开始动画回调
static void spectrum_draw_event_cb(lv_event_t * e);            // 频谱绘制事件
static lv_obj_t * album_img_create(lv_obj_t * parent);         // 创建专辑图片
static void album_gesture_event_cb(lv_event_t * e);            // 专辑手势事件
static void play_event_click_cb(lv_event_t * e);               // 播放点击事件
static void prev_click_event_cb(lv_event_t * e);               // 上一首点击事件
static void next_click_event_cb(lv_event_t * e);               // 下一首点击事件
static void timer_cb(lv_timer_t * t);                          // 定时器回调
static void track_load(uint32_t id);                           // 加载歌曲
static void stop_start_anim(lv_timer_t * t);                   // 停止开始动画
static void spectrum_end_cb(lv_anim_t * a);                    // 频谱结束回调

// 数学辅助函数
static int32_t get_cos(int32_t deg, int32_t a);                // 获取余弦值
static int32_t get_sin(int32_t deg, int32_t a);                // 获取正弦值

// 添加进度条事件回调函数
static void slider_event_cb(lv_event_t * e);                   // 进度条事件回调

void sport_song_list_icon_click_cb(lv_event_t * e);

/**********************
 *  STATIC VARIABLES
 **********************/
lv_obj_t * main_cont;           // 主容器对象
lv_obj_t * spectrum_obj;        // 频谱可视化对象
lv_obj_t * title_label;         // 标题标签
lv_obj_t * artist_label;        // 艺术家标签
lv_obj_t * genre_label;         // 流派标签
lv_obj_t * condition_label;         // 运动标签

lv_obj_t * time_obj;            // 时间显示对象
lv_obj_t * album_img_obj;       // 专辑图片对象
lv_obj_t * slider_obj;          // 进度条对象

static uint32_t spectrum_i = 0;                // 当前频谱索引
static uint32_t spectrum_i_pause = 0;          // 暂停时的频谱索引
static uint32_t bar_ofs = 0;                   // 频谱条偏移
static uint32_t spectrum_lane_ofs_start = 0;   // 频谱通道偏移开始
static uint32_t bar_rot = 0;                   // 频谱条旋转
static uint32_t time_act;                      // 当前播放时间

static lv_timer_t * sec_counter_timer;         // 秒计数器定时器
const lv_font_t * font_small;           // 小字体
const lv_font_t * font_large;           // 大字体
uint32_t track_id;                      // 当前歌曲ID
static bool playing;                           // 播放状态标志
static bool start_anim;                        // 开始动画标志

static bool slider_dragging = false;           // 进度条拖动状态标志
static lv_anim_t * spectrum_anim = NULL;       // 频谱动画对象指针

static lv_coord_t start_anim_values[40];       // 开始动画值数组
static lv_obj_t * play_obj;                    // 播放按钮对象

// 频谱数据指针和长度
static const uint16_t (* spectrum)[4];         // 频谱数据数组指针
static uint32_t spectrum_len;                  // 频谱数据长度

static void popup_item_event_cb(lv_event_t * e);
static void popup_bg_event_cb(lv_event_t * e);
static void custom_info_confirm_cb(lv_event_t * e);

// 随机数数组，用于动画效果
static const uint16_t rnd_array[30] = {
    994, 285, 553, 11, 792, 707, 966, 641, 852, 827,
    44, 352, 146, 581, 490, 80, 729, 58, 695, 940,
    724, 561, 124, 653, 27, 292, 557, 506, 382, 199
};

//弹窗控制功能
static void import_icon_click_cb(lv_event_t * e);
static void import_popup_item_event_cb(lv_event_t * e);
static void import_popup_close_event_cb(lv_event_t * e);
static void import_popup_close_event_cb_to_setting(lv_event_t * e);


// 全局变量记录导入弹窗对象
static lv_obj_t * import_popup_bg = NULL;

// 函数声明
static void custom_info_confirm_cb(lv_event_t * e);


/**********************
 *   GLOBAL FUNCTIONS
 **********************/

/*
 * 图像缩放动画回调适配器函数
 * 用于转换参数类型以避免编译时警告
 */
static void _img_set_zoom_anim_cb(void * obj, int32_t zoom) {
  lv_img_set_zoom((lv_obj_t*)obj, (uint16_t)zoom);
}

/*
 * 对象X坐标设置动画回调适配器函数
 * 用于转换参数类型以避免编译时警告
 */
static void _obj_set_x_anim_cb(void * obj, int32_t x) {
  lv_obj_set_x((lv_obj_t*)obj, (lv_coord_t)x);
}

//=====第一部分结束============================================================================================================================//
//=====第二部分：主创建函数和播放控制函数======================================================================================================//

/**
 * @brief 创建音乐播放器主界面
 * @param parent 父对象
 * @return 创建的主容器对象
 *
 * 这是音乐播放器的核心创建函数，负责：
 * - 初始化字体和界面组件
 * - 设置复杂的网格布局
 * - 创建各种动画效果
 * - 处理不同屏幕尺寸的适配
 */
lv_obj_t * _lv_demo_music_main_create(lv_obj_t * parent)
{
    // 根据屏幕尺寸选择字体大小
#if LV_DEMO_MUSIC_LARGE
    font_small = &ShiYuan_black_Normal_16;   // 大屏小字体
    font_large = &ShiYuan_black_Normal_22;   // 大屏大字体
#else
    font_small = &ShiYuan_black_Normal_12;   // 小屏小字体
    font_large = &ShiYuan_black_Normal_16;   // 小屏大字体
#endif

    /* ========== 创建音乐播放器的各个组件 ========== */
    lv_obj_t * cont = create_cont(parent);         // 创建主容器
    create_wave_images(cont);                      // 创建波浪背景图像
    lv_obj_t * title_box = create_title_box(cont); // 创建标题信息框
    lv_obj_t * icon_box = create_icon_box(cont);   // 创建图标框
    lv_obj_t * ctrl_box = create_ctrl_box(cont);   // 创建控制按钮框
    spectrum_obj = create_spectrum_obj(cont);      // 创建频谱可视化对象
    lyric_obj = lv_demo_music_lyric_create(cont);  // 创建歌词显示对象
    lv_obj_t * handle_box = create_handle(cont);   // 创建手柄区域

    // 圆形屏幕的特殊边距设置
#if LV_DEMO_MUSIC_ROUND
    lv_obj_set_style_pad_hor(cont, LV_HOR_RES / 6, 0);
#endif

    /* ========== 使用网格布局排列所有组件 ========== */

    // 方形或圆形屏幕的网格布局
#if LV_DEMO_MUSIC_SQUARE || LV_DEMO_MUSIC_ROUND
    static const lv_coord_t grid_cols[] = {LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST};
    static lv_coord_t grid_rows[] = {
        LV_DEMO_MUSIC_HANDLE_SIZE,     /* 顶部间距 */
        0,                             /* 频谱对象，稍后设置高度 */
        LV_GRID_FR(3),                 /* 间隔区域 */
        LV_GRID_CONTENT,               /* 歌词框 */
        LV_GRID_FR(3),                 /* 间隔区域 */
        LV_GRID_CONTENT,               /* 标题框 */
        LV_GRID_FR(3),                 /* 间隔区域 */
        LV_GRID_CONTENT,               /* 图标框 */
        LV_GRID_FR(3),                 /* 间隔区域 */
        LV_GRID_CONTENT,               /* 控制框 */
        LV_GRID_FR(3),                 /* 间隔区域 */
        LV_GRID_CONTENT,               /* 手柄框 */
        LV_DEMO_MUSIC_HANDLE_SIZE,     /* 底部间距 */
        LV_GRID_TEMPLATE_LAST
    };

    grid_rows[1] = LV_VER_RES;  // 设置频谱对象高度为屏幕高度

    lv_obj_set_grid_dsc_array(cont, grid_cols, grid_rows);
    lv_obj_set_style_grid_row_align(cont, LV_GRID_ALIGN_SPACE_BETWEEN, 0);
    // 将各个组件放置到网格中
    lv_obj_set_grid_cell(spectrum_obj, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_CENTER, 1, 1);
    lv_obj_set_grid_cell(lyric_obj, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_CENTER, 3, 1);
    lv_obj_set_grid_cell(title_box, LV_GRID_ALIGN_STRETCH, 0, 1, LV_ALIGN_CENTER, 5, 1);
    lv_obj_set_grid_cell(icon_box, LV_GRID_ALIGN_STRETCH, 0, 1, LV_ALIGN_CENTER, 7, 1);
    lv_obj_set_grid_cell(ctrl_box, LV_GRID_ALIGN_STRETCH, 0, 1, LV_ALIGN_CENTER, 9, 1);
    lv_obj_set_grid_cell(handle_box, LV_GRID_ALIGN_STRETCH, 0, 1, LV_ALIGN_CENTER, 11, 1);
#endif

    /* ========== 创建和管理定时器 ========== */
    sec_counter_timer = lv_timer_create(timer_cb, 1000, NULL);  // 创建1秒间隔的定时器
    lv_timer_pause(sec_counter_timer);  // 初始暂停定时器

    /* ========== 设置开始动画效果 ========== */
    lv_anim_t a;
    start_anim = true;  // 启用开始动画标志
    // 创建停止开始动画的定时器
    lv_timer_t * timer = lv_timer_create(stop_start_anim, INTRO_TIME + 6000, NULL);
    lv_timer_set_repeat_count(timer, 1);

    // 设置频谱条的进入动画
    lv_anim_init(&a);
    lv_anim_set_path_cb(&a, lv_anim_path_bounce);  // 使用弹跳动画路径

    uint32_t i;
    lv_anim_set_exec_cb(&a, start_anim_cb);
    for(i = 0; i < BAR_CNT; i++) {
        lv_anim_set_values(&a, LV_HOR_RES, 5);  // 从屏幕外移动到5像素位置
        lv_anim_set_delay(&a, INTRO_TIME - 200 + rnd_array[i] % 200);  // 随机延迟
        lv_anim_set_time(&a, 2500 + rnd_array[i] % 500);  // 随机持续时间
        lv_anim_set_var(&a, &start_anim_values[i]);  // 设置动画变量
        lv_anim_start(&a);
    }
    /* ========== 设置组件的淡入动画 ========== */
    lv_obj_fade_in(title_box, 1000, INTRO_TIME + 1000);     // 标题框淡入
    lv_obj_fade_in(icon_box, 1000, INTRO_TIME + 1000);      // 图标框淡入
    lv_obj_fade_in(ctrl_box, 1000, INTRO_TIME + 1000);      // 控制框淡入
    lv_obj_fade_in(handle_box, 1000, INTRO_TIME + 1000);    // 手柄淡入
    lv_obj_fade_in(album_img_obj, 800, INTRO_TIME + 1000);  // 专辑图片淡入
    lv_obj_fade_in(spectrum_obj, 0, INTRO_TIME);            // 频谱对象立即显示

    /* ========== 专辑图片的缩放动画 ========== */
    lv_anim_set_path_cb(&a, lv_anim_path_ease_out);
    lv_anim_set_var(&a, album_img_obj);
    lv_anim_set_time(&a, 1000);
    lv_anim_set_delay(&a, INTRO_TIME + 1000);
    lv_anim_set_values(&a, 1, LV_IMG_ZOOM_NONE);  // 从很小缩放到正常大小
    lv_anim_set_exec_cb(&a, _img_set_zoom_anim_cb);
    lv_anim_set_ready_cb(&a, NULL);
    lv_anim_start(&a);

    /* ========== 创建介绍界面的Logo和标题 ========== */
    LV_IMG_DECLARE(img_lv_demo_music_logo);
    lv_obj_t * logo = lv_img_create(lv_scr_act());
    lv_img_set_src(logo, &img_lv_demo_music_logo);
    lv_obj_move_foreground(logo);  // 将Logo移到最前面

    lv_obj_align_to(logo, spectrum_obj, LV_ALIGN_CENTER, 0, 0);

    // Logo的缩放和删除动画
    lv_anim_set_path_cb(&a, lv_anim_path_ease_in);
    lv_anim_set_var(&a, logo);
    lv_anim_set_time(&a, 400);
    lv_anim_set_delay(&a, INTRO_TIME + 800);
    lv_anim_set_values(&a, LV_IMG_ZOOM_NONE, 10);  // 放大并消失
    lv_anim_set_ready_cb(&a, lv_obj_del_anim_ready_cb);  // 动画完成后删除对象
    lv_anim_start(&a);

    lv_obj_update_layout(main_cont);  // 更新布局

    // 在界面创建完成后，立即加载第一首歌的歌词
    track_id = 0;  // 确保track_id设置为0（第一首歌）
    lv_demo_music_lyric_set_track(track_id);  // 强制加载第一首歌的歌词
    lv_demo_music_mp3_set_track(track_id);  // 强制播放第一首歌
    mp3_pause();

    // 如果当前正在播放，也更新时间显示
    if (playing) {
        lv_demo_music_lyric_update_time(0);  // 从0时间开始
    }

    return main_cont;
}

/**
 * @brief 切换到下一首或上一首专辑
 * @param next true切换到下一首，false切换到上一首
 *
 * 处理专辑切换逻辑，支持循环播放
 */
void _lv_demo_music_album_next(bool next)
{
    // 用户主动切换歌曲，退出运动歌单模式
    lv_demo_music_switch_to_normal_playlist();

    uint32_t id = track_id;

    // 计算下一个歌曲ID
    if(next) {
        id++;
        if(id >= track_count) id = 0;  // 循环到第一首
    } else {
        if(id == 0) {
            id = track_count - 1;  // 循环到最后一首
        } else {
            id--;
        }
    }

    // 根据当前播放状态加载歌曲
    if(playing) {
        _lv_demo_music_play(id);  // 如果正在播放，直接播放新歌曲
        mp3_pause();
        mp3_resume_playback();
    } else {
        track_load(id);  // 如果暂停，只加载歌曲信息
        mp3_pause();
    }
}

/**
 * @brief 播放指定ID的歌曲
 * @param id 歌曲ID
 *
 * 加载并播放指定歌曲
 */
void _lv_demo_music_play(uint32_t id)
{
    track_load(id);      // 加载歌曲信息
    _lv_demo_music_resume();  // 恢复播放
}

/**
 * @brief 恢复播放当前歌曲
 *
 * 从暂停状态恢复播放，重新启动频谱动画和计时器
 */
void _lv_demo_music_resume(void)
{
    playing = true;
    spectrum_i = spectrum_i_pause;

    // 设置频谱动画
    lv_anim_t a;
    lv_anim_init(&a);
    lv_anim_set_values(&a, spectrum_i, spectrum_len - 1);
    lv_anim_set_exec_cb(&a, spectrum_anim_cb);
    lv_anim_set_var(&a, spectrum_obj);
    lv_anim_set_time(&a, ((spectrum_len - spectrum_i) * 1000) / 30);
    lv_anim_set_playback_time(&a, 0);
    lv_anim_set_ready_cb(&a, spectrum_end_cb);

    // 保存动画对象指针以便后续控制
    spectrum_anim = lv_anim_start(&a);

    // 恢复定时器和进度条
    lv_timer_resume(sec_counter_timer);
    lv_slider_set_range(slider_obj, 0, _lv_demo_music_get_track_length(track_id));

    lv_obj_add_state(play_obj, LV_STATE_CHECKED);
}

/**
 * @brief 暂停当前播放
 */
void _lv_demo_music_pause(void)
{
    playing = false;
    spectrum_i_pause = spectrum_i;
    spectrum_i = 0;

    // 删除频谱动画
    lv_anim_del(spectrum_obj, spectrum_anim_cb);
    spectrum_anim = NULL;

    lv_obj_invalidate(spectrum_obj);
    lv_img_set_zoom(album_img_obj, LV_IMG_ZOOM_NONE);
    lv_timer_pause(sec_counter_timer);
    lv_obj_clear_state(play_obj, LV_STATE_CHECKED);
}

//=====第二部分结束============================================================================================================================//
//=====第三部分：界面组件创建函数==============================================================================================================//

/**********************
 *   STATIC FUNCTIONS
 **********************/

/**
 * @brief 创建主容器和滚动结构
 * @param parent 父对象
 * @return 创建的播放器容器对象
 *
 * 创建复杂的滚动容器结构，支持上下滑动切换界面
 */
static lv_obj_t * create_cont(lv_obj_t * parent)
{
    /* 创建一个透明的容器，播放器部分将在其中滚动 */
    main_cont = lv_obj_create(parent);
    lv_obj_clear_flag(main_cont, LV_OBJ_FLAG_CLICKABLE);      // 禁止点击
    lv_obj_clear_flag(main_cont, LV_OBJ_FLAG_SCROLL_ELASTIC); // 禁用弹性滚动
    lv_obj_remove_style_all(main_cont);                       // 移除所有样式，使其透明
    lv_obj_set_size(main_cont, lv_pct(100), lv_pct(100));     // 设置全屏大小
    lv_obj_set_scroll_snap_y(main_cont, LV_SCROLL_SNAP_CENTER); // 设置垂直滚动居中对齐

    /* 创建播放器的主容器 */
    lv_obj_t * player = lv_obj_create(main_cont);
    lv_obj_set_y(player, -LV_DEMO_MUSIC_HANDLE_SIZE);  // 初始位置向上偏移

    // 根据屏幕类型设置容器大小
#if LV_DEMO_MUSIC_SQUARE || LV_DEMO_MUSIC_ROUND
    lv_obj_set_size(player, LV_HOR_RES, 3 * LV_VER_RES + LV_DEMO_MUSIC_HANDLE_SIZE * 2);
#else
    lv_obj_set_size(player, LV_HOR_RES, LV_VER_RES + lv_demo_music_lyric_get_height() + LV_DEMO_MUSIC_HANDLE_SIZE * 2);
#endif
    lv_obj_clear_flag(player, LV_OBJ_FLAG_SNAPABLE);  // 清除对齐标记

    // 设置播放器样式
    lv_obj_set_style_bg_color(player, lv_color_hex(0xffffff), 0);  // 白色背景
    lv_obj_set_style_border_width(player, 0, 0);                   // 无边框
    lv_obj_set_style_pad_all(player, 0, 0);                        // 无内边距
    lv_obj_set_scroll_dir(player, LV_DIR_VER);                     // 允许垂直滚动

    /* 创建透明的占位符对象，用于滚动对齐 */

    // 第一个占位符
    lv_obj_t * placeholder1 = lv_obj_create(main_cont);
    lv_obj_remove_style_all(placeholder1);
    lv_obj_clear_flag(placeholder1, LV_OBJ_FLAG_CLICKABLE);
    // 调试时可取消注释查看占位符位置
    // lv_obj_set_style_bg_color(placeholder1, lv_color_hex(0xff0000), 0);
    // lv_obj_set_style_bg_opa(placeholder1, LV_OPA_50, 0);

    // 第二个占位符
    lv_obj_t * placeholder2 = lv_obj_create(main_cont);
    lv_obj_remove_style_all(placeholder2);
    lv_obj_clear_flag(placeholder2, LV_OBJ_FLAG_CLICKABLE);
    // lv_obj_set_style_bg_color(placeholder2, lv_color_hex(0x00ff00), 0);
    // lv_obj_set_style_bg_opa(placeholder2, LV_OPA_50, 0);

    // 第三个占位符
    lv_obj_t * placeholder3 = lv_obj_create(main_cont);
    lv_obj_remove_style_all(placeholder3);
    lv_obj_clear_flag(placeholder3, LV_OBJ_FLAG_CLICKABLE);

    // 第三个占位符
    lv_obj_t * placeholder4 = lv_obj_create(main_cont);
    lv_obj_remove_style_all(placeholder4);
    lv_obj_clear_flag(placeholder4, LV_OBJ_FLAG_CLICKABLE);

    // 方形或圆形屏幕需要第三个占位符
#if LV_DEMO_MUSIC_SQUARE || LV_DEMO_MUSIC_ROUND
    // 方形/圆形屏幕：三个页面
    lv_obj_set_size(placeholder1, lv_pct(100), LV_VER_RES);
    lv_obj_set_y(placeholder1, 0);

    lv_obj_set_size(placeholder2, lv_pct(100), LV_VER_RES);
    lv_obj_set_y(placeholder2, LV_VER_RES);

    lv_obj_set_size(placeholder3, lv_pct(100), LV_VER_RES);
    lv_obj_set_y(placeholder3, 2 * LV_VER_RES);

    lv_obj_set_size(placeholder4, lv_pct(100), LV_VER_RES - 2 * LV_DEMO_MUSIC_HANDLE_SIZE);
    lv_obj_set_y(placeholder4, 3 * LV_VER_RES + LV_DEMO_MUSIC_HANDLE_SIZE);

#endif

    lv_obj_update_layout(main_cont);  // 更新布局计算

    return player;
}

/**
 * @brief 创建波浪背景图像
 * @param parent 父对象
 *
 * 在界面顶部和底部添加装饰性的波浪图像
 */
static void create_wave_images(lv_obj_t * parent)
{
    // 声明波浪图像资源
    LV_IMG_DECLARE(img_lv_demo_music_wave_top);
    LV_IMG_DECLARE(img_lv_demo_music_wave_bottom);

    // 创建顶部波浪图像
    lv_obj_t * wave_top = lv_img_create(parent);
    lv_img_set_src(wave_top, &img_lv_demo_music_wave_top);
    lv_obj_set_width(wave_top, LV_HOR_RES);  // 设置宽度为屏幕宽度
    lv_obj_align(wave_top, LV_ALIGN_TOP_MID, 0, 0);
    lv_obj_add_flag(wave_top, LV_OBJ_FLAG_IGNORE_LAYOUT);  // 忽略布局计算

    // 创建底部波浪图像
    lv_obj_t * wave_bottom = lv_img_create(parent);
    lv_img_set_src(wave_bottom, &img_lv_demo_music_wave_bottom);
    lv_obj_set_width(wave_bottom, LV_HOR_RES);
    lv_obj_align(wave_bottom, LV_ALIGN_BOTTOM_MID, 0, 0);
    lv_obj_add_flag(wave_bottom, LV_OBJ_FLAG_IGNORE_LAYOUT);

    // 创建角落装饰图像
    LV_IMG_DECLARE(img_lv_demo_music_corner_left);
    LV_IMG_DECLARE(img_lv_demo_music_corner_right);

    // 左下角图像
    lv_obj_t * wave_corner = lv_img_create(parent);
    lv_img_set_src(wave_corner, &img_lv_demo_music_corner_left);
#if LV_DEMO_MUSIC_ROUND == 0
    lv_obj_align(wave_corner, LV_ALIGN_BOTTOM_LEFT, 0, 0);  // 普通屏幕对齐
#else
    lv_obj_align(wave_corner, LV_ALIGN_BOTTOM_LEFT, -LV_HOR_RES / 6, 0);  // 圆形屏幕偏移
#endif
    lv_obj_add_flag(wave_corner, LV_OBJ_FLAG_IGNORE_LAYOUT);

    // 右下角图像
    wave_corner = lv_img_create(parent);
    lv_img_set_src(wave_corner, &img_lv_demo_music_corner_right);
#if LV_DEMO_MUSIC_ROUND == 0
    lv_obj_align(wave_corner, LV_ALIGN_BOTTOM_RIGHT, 0, 0);
#else
    lv_obj_align(wave_corner, LV_ALIGN_BOTTOM_RIGHT, LV_HOR_RES / 6, 0);
#endif
    lv_obj_add_flag(wave_corner, LV_OBJ_FLAG_IGNORE_LAYOUT);
}

/**
 * @brief 创建歌曲信息标题框
 * @param parent 父对象
 * @return 创建的标题容器对象
 *
 * 创建显示歌曲标题、艺术家和流派的区域
 */
static lv_obj_t * create_title_box(lv_obj_t * parent)
{
    // 创建标题容器
    lv_obj_t * cont = lv_obj_create(parent);
    lv_obj_remove_style_all(cont);              // 移除默认样式
    lv_obj_set_height(cont, LV_SIZE_CONTENT);   // 高度根据内容自适应
    lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_COLUMN);  // 垂直流式布局
    lv_obj_set_flex_align(cont, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
    // 创建歌曲标题标签
    title_label = lv_label_create(cont);
    lv_obj_set_style_text_font(title_label, font_large, 0);        // 大字体
    lv_obj_set_style_text_color(title_label, lv_color_hex(0x504d6d), 0);  // 深蓝色文字
    lv_label_set_text(title_label, _lv_demo_music_get_title(track_id));  // 设置初始文本
    lv_obj_set_height(title_label, lv_font_get_line_height(font_large)*0.9);  // 设置合适高度

    // 创建艺术家标签
    artist_label = lv_label_create(cont);
    lv_obj_set_style_text_font(artist_label, font_small, 0);       // 小字体
    lv_obj_set_style_text_color(artist_label, lv_color_hex(0x504d6d), 0);
    lv_label_set_text(artist_label, _lv_demo_music_get_artist(track_id));

    // 创建水平容器来放置流派和运动标签
    lv_obj_t * hor_cont = lv_obj_create(cont);
    lv_obj_remove_style_all(hor_cont);
    lv_obj_set_size(hor_cont, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
    lv_obj_set_flex_flow(hor_cont, LV_FLEX_FLOW_ROW);  // 改为水平布局
    lv_obj_set_flex_align(hor_cont, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
    lv_obj_set_style_pad_all(hor_cont, 0, 0);
    lv_obj_set_style_bg_opa(hor_cont, LV_OPA_0, 0);  // 透明背景
    // 创建流派标签
    genre_label = lv_label_create(hor_cont);
    lv_obj_set_style_text_font(genre_label, font_small, 0);
    lv_obj_set_style_text_color(genre_label, lv_color_hex(0x8a86b8), 0);
    lv_label_set_text(genre_label, _lv_demo_music_get_genre(track_id));

    // 添加分隔符（可选）
    lv_obj_t * separator = lv_label_create(hor_cont);
    lv_label_set_text(separator, " | ");
    lv_obj_set_style_text_font(separator, font_small, 0);
    lv_obj_set_style_text_color(separator, lv_color_hex(0x8a86b8), 0);
    lv_obj_set_style_pad_hor(separator, 8, 0);  // 左右间距

    // 创建运动标签
    condition_label = lv_label_create(hor_cont);
    lv_obj_set_style_text_font(condition_label, font_small, 0);
    lv_obj_set_style_text_color(condition_label, lv_color_hex(0x8a86b8), 0);
    lv_label_set_text(condition_label, condition_list[track_id]);
    return cont;
}

/**
 * @brief 创建图标显示框
 * @param parent 父对象
 * @return 创建的图标容器对象
 *
 * 创建显示装饰性图标的水平排列区域
 */
static lv_obj_t * create_icon_box(lv_obj_t * parent)
{
    // 创建图标容器
    lv_obj_t * cont = lv_obj_create(parent);
    lv_obj_remove_style_all(cont);
    lv_obj_set_height(cont, LV_SIZE_CONTENT);
    lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_ROW);
    lv_obj_set_flex_align(cont, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);

    // 声明前三个图片图标
    LV_IMG_DECLARE(img_lv_demo_music_icon_1);
    LV_IMG_DECLARE(img_lv_demo_music_icon_2);
    LV_IMG_DECLARE(img_lv_demo_music_icon_3);

    lv_obj_t * icon;

    // 前三个使用图片图标 - 创建容器来统一尺寸，图片居中显示
    for(int i = 0; i < 3; i++) {
        // 创建固定尺寸的容器
        lv_obj_t * icon_cont = lv_obj_create(cont);
        lv_obj_remove_style_all(icon_cont);
        lv_obj_set_size(icon_cont, 44, 44);  // 统一容器尺寸
        lv_obj_set_flex_flow(icon_cont, LV_FLEX_FLOW_ROW);
        lv_obj_set_flex_align(icon_cont, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
        lv_obj_set_style_bg_opa(icon_cont, LV_OPA_0, 0);

        // 创建图片并居中
        icon = lv_img_create(icon_cont);
        switch(i) {
            case 0:
                lv_img_set_src(icon, &img_lv_demo_music_icon_1);
                break;
            case 1: lv_img_set_src(icon, &img_lv_demo_music_icon_2);
               break;
            case 2: lv_img_set_src(icon, &img_lv_demo_music_icon_3); break;
        }
        // 图片保持原始尺寸，在容器中居中
        lv_obj_center(icon);
    }

    // 第四个使用设置符号图标 - 保持44x44
    lv_obj_t * settings_btn = lv_btn_create(cont);
    lv_obj_remove_style_all(settings_btn);
    lv_obj_set_size(settings_btn, 44, 44);
    lv_obj_set_style_bg_opa(settings_btn, LV_OPA_0, 0);
    lv_obj_set_style_bg_opa(settings_btn, LV_OPA_20, LV_STATE_PRESSED);
    lv_obj_set_style_bg_color(settings_btn, lv_color_hex(0x504d6d), LV_STATE_PRESSED);
    lv_obj_set_style_radius(settings_btn, 22, 0);
    lv_obj_add_flag(settings_btn, LV_OBJ_FLAG_CLICKABLE);

    // 使用项目中已有的字体
    lv_obj_t * settings_icon = lv_label_create(settings_btn);
    lv_label_set_text(settings_icon, LV_SYMBOL_SETTINGS);
    lv_obj_set_style_text_font(settings_icon, &lv_font_montserrat_20, 0);
    lv_obj_set_style_text_color(settings_icon, lv_color_hex(0x504d6d), 0);
    lv_obj_center(settings_icon);

    // 添加点击事件
    lv_obj_add_event_cb(settings_btn, settings_icon_click_cb, LV_EVENT_CLICKED, NULL);


    return cont;
}

/**
 * @brief 创建频谱可视化对象
 * @param parent 父对象
 * @return 创建的频谱对象
 *
 * 创建用于显示音乐频谱动画的特殊绘制对象
 */
static lv_obj_t * create_spectrum_obj(lv_obj_t * parent)
{
    /* 创建频谱可视化器对象 */
    lv_obj_t * obj = lv_obj_create(parent);
    lv_obj_remove_style_all(obj);  // 移除所有默认样式

    // 设置频谱对象高度
#if LV_DEMO_MUSIC_LARGE
    lv_obj_set_height(obj, 500);   // 大屏高度
#else
    lv_obj_set_height(obj, 250);   // 小屏高度
#endif

    // 清除不必要的标志
    lv_obj_clear_flag(obj, LV_OBJ_FLAG_CLICKABLE | LV_OBJ_FLAG_SCROLLABLE);
    lv_obj_add_event_cb(obj, spectrum_draw_event_cb, LV_EVENT_ALL, NULL);  // 添加绘制事件
    lv_obj_refresh_ext_draw_size(obj);  // 刷新外部绘制大小

    album_img_obj = album_img_create(obj);  // 在频谱对象中创建专辑图片

    return obj;
}

/**
 * @brief 创建播放控制框
 * @param parent 父对象
 * @return 创建的控制容器对象
 *
 * 创建包含播放控制按钮和进度条的控制区域
 */
static lv_obj_t * create_ctrl_box(lv_obj_t * parent)
{
    /* 创建控制框容器 */
    lv_obj_t * cont = lv_obj_create(parent);
    lv_obj_remove_style_all(cont);
    lv_obj_set_height(cont, LV_SIZE_CONTENT);

    // 设置底部内边距
#if LV_DEMO_MUSIC_LARGE
    lv_obj_set_style_pad_bottom(cont, 17, 0);  // 大屏底部间距
#else
    lv_obj_set_style_pad_bottom(cont, 8, 0);   // 小屏底部间距
#endif

    // 定义控制框的网格布局
    static const lv_coord_t grid_col[] = {
        LV_GRID_FR(2),  // 左边距
        LV_GRID_FR(3),  // 随机按钮
        LV_GRID_FR(5),  // 上一首按钮
        LV_GRID_FR(5),  // 播放/暂停按钮
        LV_GRID_FR(5),  // 下一首按钮
        LV_GRID_FR(3),  // 循环按钮
        LV_GRID_FR(2),  // 右边距
        LV_GRID_TEMPLATE_LAST
    };
    static const lv_coord_t grid_row[] = {
        LV_GRID_CONTENT,  // 按钮行
        LV_GRID_CONTENT,  // 进度条行
        LV_GRID_TEMPLATE_LAST
    };
    lv_obj_set_grid_dsc_array(cont, grid_col, grid_row);

    // 声明控制按钮图像资源
    LV_IMG_DECLARE(img_lv_demo_music_btn_loop);
    LV_IMG_DECLARE(img_lv_demo_music_btn_rnd);
    LV_IMG_DECLARE(img_lv_demo_music_btn_next);
    LV_IMG_DECLARE(img_lv_demo_music_btn_prev);
    LV_IMG_DECLARE(img_lv_demo_music_btn_play);
    LV_IMG_DECLARE(img_lv_demo_music_btn_pause);

    lv_obj_t * icon;

    // 创建随机播放按钮
    icon = lv_img_create(cont);
    lv_img_set_src(icon, &img_lv_demo_music_btn_rnd);
    lv_obj_set_grid_cell(icon, LV_GRID_ALIGN_START, 1, 1, LV_GRID_ALIGN_CENTER, 0, 1);

    // 创建循环播放按钮
    icon = lv_img_create(cont);
    lv_img_set_src(icon, &img_lv_demo_music_btn_loop);
    lv_obj_set_grid_cell(icon, LV_GRID_ALIGN_END, 5, 1, LV_GRID_ALIGN_CENTER, 0, 1);

    // 创建上一首按钮并添加点击事件
    icon = lv_img_create(cont);
    lv_img_set_src(icon, &img_lv_demo_music_btn_prev);
    lv_obj_set_grid_cell(icon, LV_GRID_ALIGN_CENTER, 2, 1, LV_GRID_ALIGN_CENTER, 0, 1);
    lv_obj_add_event_cb(icon, prev_click_event_cb, LV_EVENT_CLICKED, NULL);
    lv_obj_add_flag(icon, LV_OBJ_FLAG_CLICKABLE);

    // 创建播放/暂停按钮（可切换状态）
    play_obj = lv_imgbtn_create(cont);
    lv_imgbtn_set_src(play_obj, LV_IMGBTN_STATE_RELEASED, NULL, &img_lv_demo_music_btn_play, NULL);
    lv_imgbtn_set_src(play_obj, LV_IMGBTN_STATE_CHECKED_RELEASED, NULL, &img_lv_demo_music_btn_pause, NULL);
    lv_obj_add_flag(play_obj, LV_OBJ_FLAG_CHECKABLE);  // 设置为可切换状态
    lv_obj_set_grid_cell(play_obj, LV_GRID_ALIGN_CENTER, 3, 1, LV_GRID_ALIGN_CENTER, 0, 1);
    lv_obj_add_event_cb(play_obj, play_event_click_cb, LV_EVENT_CLICKED, NULL);
    lv_obj_add_flag(play_obj, LV_OBJ_FLAG_CLICKABLE);
    lv_obj_set_width(play_obj, img_lv_demo_music_btn_play.header.w);  // 设置按钮宽度

    // 创建下一首按钮并添加点击事件
    icon = lv_img_create(cont);
    lv_img_set_src(icon, &img_lv_demo_music_btn_next);
    lv_obj_set_grid_cell(icon, LV_GRID_ALIGN_CENTER, 4, 1, LV_GRID_ALIGN_CENTER, 0, 1);
    lv_obj_add_event_cb(icon, next_click_event_cb, LV_EVENT_CLICKED, NULL);
    lv_obj_add_flag(icon, LV_OBJ_FLAG_CLICKABLE);

    // 创建进度条滑块
    LV_IMG_DECLARE(img_lv_demo_music_slider_knob);
    slider_obj = lv_slider_create(cont);
    lv_obj_set_style_anim_time(slider_obj, 100, 0);  // 设置动画时间
    lv_obj_add_flag(slider_obj, LV_OBJ_FLAG_CLICKABLE);  // 允许点击但不接受输入

    // 添加进度条事件回调
    lv_obj_add_event_cb(slider_obj, slider_event_cb, LV_EVENT_ALL, NULL);

    // 设置进度条高度
#if LV_DEMO_MUSIC_LARGE == 0
    lv_obj_set_height(slider_obj, 3);  // 小屏高度
#else
    lv_obj_set_height(slider_obj, 6);  // 大屏高度
#endif
    lv_obj_set_grid_cell(slider_obj, LV_GRID_ALIGN_STRETCH, 1, 4, LV_GRID_ALIGN_CENTER, 1, 1);

    // 设置进度条样式
    lv_obj_set_style_bg_img_src(slider_obj, &img_lv_demo_music_slider_knob, LV_PART_KNOB);  // 滑块图像
    lv_obj_set_style_bg_opa(slider_obj, LV_OPA_TRANSP, LV_PART_KNOB);  // 透明滑块背景
    lv_obj_set_style_pad_all(slider_obj, 20, LV_PART_KNOB);  // 滑块内边距
    lv_obj_set_style_bg_grad_dir(slider_obj, LV_GRAD_DIR_HOR, LV_PART_INDICATOR);  // 水平渐变
    lv_obj_set_style_bg_color(slider_obj, lv_color_hex(0x569af8), LV_PART_INDICATOR);  // 蓝色
    lv_obj_set_style_bg_grad_color(slider_obj, lv_color_hex(0xa666f1), LV_PART_INDICATOR);  // 紫色
    lv_obj_set_style_outline_width(slider_obj, 0, 0);  // 无轮廓

    // 创建时间显示标签
    time_obj = lv_label_create(cont);
    lv_obj_set_style_text_font(time_obj, font_small, 0);
    lv_obj_set_style_text_color(time_obj, lv_color_hex(0x8a86b8), 0);
    lv_label_set_text(time_obj, "0:00");  // 初始时间
    lv_obj_set_grid_cell(time_obj, LV_GRID_ALIGN_END, 5, 1, LV_GRID_ALIGN_CENTER, 1, 1);

    return cont;
}

/**
 * @brief 创建滑动指示手柄
 * @param parent 父对象
 * @return 创建的手柄容器对象
 *
 * 创建用于指示可以向下滑动查看歌曲列表的手柄区域
 */
static lv_obj_t * create_handle(lv_obj_t * parent)
{
    lv_obj_t * cont = lv_obj_create(parent);
    lv_obj_remove_style_all(cont);

    lv_obj_set_size(cont, lv_pct(100), LV_SIZE_CONTENT);  // 宽度100%，高度自适应
    lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_COLUMN);      // 垂直流式布局
    lv_obj_set_flex_align(cont, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
    lv_obj_set_style_pad_row(cont, 8, 0);  // 设置行间距

    /* 创建用于滚动到歌曲列表的手柄指示器 */

    // 手柄文字标签
    lv_obj_t * handle_label = lv_label_create(cont);
    lv_label_set_text(handle_label, "ALL TRACKS");
    lv_obj_set_style_text_font(handle_label, font_small, 0);
    lv_obj_set_style_text_color(handle_label, lv_color_hex(0x8a86b8), 0);

    // 手柄矩形指示器
    lv_obj_t * handle_rect = lv_obj_create(cont);
#if LV_DEMO_MUSIC_LARGE
    lv_obj_set_size(handle_rect, 40, 3);  // 大屏尺寸
#else
    lv_obj_set_size(handle_rect, 20, 2);  // 小屏尺寸
#endif

    lv_obj_set_style_bg_color(handle_rect, lv_color_hex(0x8a86b8), 0);  // 浅紫色
    lv_obj_set_style_border_width(handle_rect, 0, 0);  // 无边框

    return cont;
}

//=====第三部分结束============================================================================================================================//
//=====第四部分：核心功能函数和事件处理========================================================================================================//

/**
 * @brief 加载并切换歌曲
 * @param id 要加载的歌曲ID
 *
 * 处理歌曲切换的所有逻辑，包括界面更新和动画效果
 */
static void track_load(uint32_t id)
{
    // 用户主动加载歌曲，退出运动歌单模式
    lv_demo_music_switch_to_normal_playlist();

    // 重置播放状态
    spectrum_i = 0;
    time_act = 0;
    spectrum_i_pause = 0;
    lv_slider_set_value(slider_obj, 0, LV_ANIM_OFF);  // 重置进度条
    lv_label_set_text(time_obj, "0:00");              // 重置时间显示

    // 如果是同一歌曲则直接返回
    if(id == track_id) return;

    // 判断切换方向（下一首还是上一首）
    bool next = false;
    if((track_id + 1) % track_count == id) next = true;

    // 更新歌曲列表中的选中状态
    _lv_demo_music_list_btn_check(track_id, false);  // 取消之前选中的歌曲
    track_id = id;                                   // 更新当前歌曲ID
    _lv_demo_music_list_btn_check(id, true);         // 选中新歌曲

    // 更新界面显示的歌曲信息
    lv_label_set_text(title_label, _lv_demo_music_get_title(track_id));
    lv_label_set_text(artist_label, _lv_demo_music_get_artist(track_id));
    lv_label_set_text(genre_label, _lv_demo_music_get_genre(track_id));
    lv_label_set_text(condition_label, condition_list[track_id]);
    lv_demo_music_lyric_set_track(id);

    /* ========== 创建专辑图片切换动画 ========== */

    // 淡出当前专辑图片
    lv_obj_fade_out(album_img_obj, 500, 0);

    lv_anim_t a;
    lv_anim_init(&a);
    lv_anim_set_var(&a, album_img_obj);
    lv_anim_set_time(&a, 500);
    lv_anim_set_path_cb(&a, lv_anim_path_ease_out);

    // 根据切换方向设置水平移动动画
#if LV_DEMO_MUSIC_LANDSCAPE
    if(next) {
        lv_anim_set_values(&a, 0, -LV_HOR_RES / 7);  // 横屏模式向左移动
    } else {
        lv_anim_set_values(&a, 0, LV_HOR_RES / 7);   // 横屏模式向右移动
    }
#else
    if(next) {
        lv_anim_set_values(&a, 0, -LV_HOR_RES / 2);  // 竖屏模式向左移动
    } else {
        lv_anim_set_values(&a, 0, LV_HOR_RES / 2);   // 竖屏模式向右移动
    }
#endif
    lv_anim_set_exec_cb(&a, _obj_set_x_anim_cb);      // 设置X坐标动画回调
    lv_anim_set_ready_cb(&a, lv_obj_del_anim_ready_cb);  // 动画完成后删除对象
    lv_anim_start(&a);

    // 同时创建缩放动画（缩小效果）
    lv_anim_set_path_cb(&a, lv_anim_path_linear);
    lv_anim_set_var(&a, album_img_obj);
    lv_anim_set_time(&a, 500);
    lv_anim_set_values(&a, LV_IMG_ZOOM_NONE, LV_IMG_ZOOM_NONE / 2);  // 缩放到一半
    lv_anim_set_exec_cb(&a, _img_set_zoom_anim_cb);
    lv_anim_set_ready_cb(&a, NULL);
    lv_anim_start(&a);

    /* ========== 创建新专辑图片的进入动画 ========== */

    // 创建新的专辑图片
    album_img_obj = album_img_create(spectrum_obj);
    lv_obj_fade_in(album_img_obj, 500, 100);  // 淡入效果

    // 新专辑图片的缩放动画（从缩小状态弹回正常大小）
    lv_anim_set_path_cb(&a, lv_anim_path_overshoot);  // 使用 overshoot 路径（轻微过冲）
    lv_anim_set_var(&a, album_img_obj);
    lv_anim_set_time(&a, 500);
    lv_anim_set_delay(&a, 100);  // 延迟100ms开始
    lv_anim_set_values(&a, LV_IMG_ZOOM_NONE / 4, LV_IMG_ZOOM_NONE);  // 从1/4缩放到正常
    lv_anim_set_exec_cb(&a, _img_set_zoom_anim_cb);
    lv_anim_set_ready_cb(&a, NULL);
    lv_anim_start(&a);

    lv_demo_music_mp3_set_track(id);
}

/**
 * @brief 计算指定角度的余弦值
 * @param deg 角度（0-360）
 * @param a 振幅
 * @return 计算后的余弦值
 *
 * 使用LVGL的三角函数计算余弦值并进行适当的缩放和偏移
 */
int32_t get_cos(int32_t deg, int32_t a)
{
    int32_t r = (lv_trigo_cos(deg) * a);  // 计算余弦值
    r += LV_TRIGO_SIN_MAX / 2;            // 添加偏移量
    return r >> LV_TRIGO_SHIFT;           // 右移进行缩放
}

/**
 * @brief 计算指定角度的正弦值
 * @param deg 角度（0-360）
 * @param a 振幅
 * @return 计算后的正弦值
 *
 * 使用LVGL的三角函数计算正弦值并进行适当的缩放和偏移
 */
int32_t get_sin(int32_t deg, int32_t a)
{
    int32_t r = lv_trigo_sin(deg) * a;    // 计算正弦值
    r += LV_TRIGO_SIN_MAX / 2;            // 添加偏移量
    return r >> LV_TRIGO_SHIFT;           // 右移进行缩放
}

/**
 * @brief 频谱绘制事件回调
 * @param e 事件对象
 *
 * 处理频谱可视化对象的绘制事件，创建动态的音乐频谱效果
 */
static void spectrum_draw_event_cb(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);

    // 处理外部绘制大小请求
    if(code == LV_EVENT_REFR_EXT_DRAW_SIZE) {
#if LV_DEMO_MUSIC_LANDSCAPE
        lv_event_set_ext_draw_size(e, LV_HOR_RES);  // 横屏模式需要水平绘制空间
#else
        lv_event_set_ext_draw_size(e, LV_VER_RES);  // 竖屏模式需要垂直绘制空间
#endif
    }
    // 处理覆盖检查事件
    else if(code == LV_EVENT_COVER_CHECK) {
        lv_event_set_cover_res(e, LV_COVER_RES_NOT_COVER);  // 不覆盖其他对象
    }
    // 处理绘制后事件（实际绘制频谱）
    else if(code == LV_EVENT_DRAW_POST) {
        lv_obj_t * obj = lv_event_get_target(e);
        lv_draw_ctx_t * draw_ctx = lv_event_get_draw_ctx(e);

        // 检查对象透明度，如果完全透明则不绘制
        lv_opa_t opa = lv_obj_get_style_opa(obj, LV_PART_MAIN);
        if(opa < LV_OPA_MIN) return;

        // 定义绘制所需的变量
        lv_point_t poly[4];    // 多边形顶点数组（每个频谱条是四边形）
        lv_point_t center;     // 频谱中心点

        // 计算中心点坐标
        center.x = obj->coords.x1 + lv_obj_get_width(obj) / 2;
        center.y = obj->coords.y1 + lv_obj_get_height(obj) / 2;

        // 初始化矩形绘制描述符
        lv_draw_rect_dsc_t draw_dsc;
        lv_draw_rect_dsc_init(&draw_dsc);
        draw_dsc.bg_opa = LV_OPA_COVER;  // 设置不透明背景

        // 频谱条半径数组
        uint16_t r[64];
        uint32_t i;

        // 计算最小振幅和内半径
        lv_coord_t min_a = 5;  // 最小振幅
#if LV_DEMO_MUSIC_LARGE == 0
        lv_coord_t r_in = 77;  // 小屏内半径
#else
        lv_coord_t r_in = 160; // 大屏内半径
#endif
        // 根据专辑图片缩放调整内半径
        r_in = (r_in * lv_img_get_zoom(album_img_obj)) >> 8;

        // 初始化所有频谱条的半径
        for(i = 0; i < BAR_CNT; i++) r[i] = r_in + min_a;

        /* ========== 处理四个频带的频谱数据 ========== */
        uint32_t s;
        for(s = 0; s < 4; s++) {
            uint32_t f;
            uint32_t band_w = 0;  // 此频带中的实际频谱条数量

            // 根据频带索引设置不同的条数（模拟不同频率范围的细节）
            switch(s) {
            case 0:
                band_w = 20;  // 低频带，更多细节
                break;
            case 1:
                band_w = 8;   // 中低频带
                break;
            case 2:
                band_w = 4;   // 中高频带
                break;
            case 3:
                band_w = 2;   // 高频带，较少细节
                break;
            }

            /* 使用余弦特性添加"侧边条"以创建平滑的频带效果 */
            for(f = 0; f < band_w; f++) {
                uint32_t ampl_main = spectrum[spectrum_i][s];  // 主振幅
                // 计算余弦调制振幅（0-360范围）
                int32_t ampl_mod = get_cos(f * 360 / band_w + 180, 180) + 180;

                // 计算目标频谱条索引（考虑循环）
                int32_t t = BAR_PER_BAND_CNT * s - band_w / 2 + f;
                if(t < 0) t = BAR_CNT + t;
                if(t >= BAR_CNT) t = t - BAR_CNT;

                // 应用调制振幅到频谱条半径
                r[t] += (ampl_main * ampl_mod) >> 9;
            }
        }

        /* ========== 计算动画值和绘制频谱条 ========== */
        uint32_t amax = 20;  // 最大动画值
        int32_t animv = spectrum_i - spectrum_lane_ofs_start;
        if(animv > amax) animv = amax;

        // 遍历所有频谱条进行绘制
        for(i = 0; i < BAR_CNT; i++) {
            uint32_t deg_space = 1;  // 角度间距
            uint32_t deg = i * DEG_STEP + 90;  // 计算当前角度（从90度开始）

            // 使用随机数组创建动态效果，避免频谱条过于规则
            uint32_t j = (i + bar_rot + rnd_array[bar_ofs %10]) % BAR_CNT;
            uint32_t k = (i + bar_rot + rnd_array[(bar_ofs + 1) % 10]) % BAR_CNT;

            // 计算动画插值后的半径值
            uint32_t v = (r[k] * animv + r[j] * (amax - animv)) / amax;

            // 开始动画阶段的特殊处理
            if(start_anim) {
                v = r_in + start_anim_values[i];  // 使用开始动画值
                deg_space = v >> 7;               // 根据值计算角度间距
                if(deg_space < 1) deg_space = 1;
            }

            /* ========== 根据半径值设置频谱条颜色 ========== */
            if(v < BAR_COLOR1_STOP)
                draw_dsc.bg_color = BAR_COLOR1;  // 小振幅：浅紫色
            else if(v > BAR_COLOR3_STOP)
                draw_dsc.bg_color = BAR_COLOR3;  // 大振幅：白色
            else if(v > BAR_COLOR2_STOP)
                // 中高振幅：蓝色到白色的渐变
                draw_dsc.bg_color = lv_color_mix(BAR_COLOR3, BAR_COLOR2,
                    ((v - BAR_COLOR2_STOP) * 255) / (BAR_COLOR3_STOP-BAR_COLOR2_STOP));
            else
                // 中低振幅：浅紫色到蓝色的渐变
                draw_dsc.bg_color = lv_color_mix(BAR_COLOR2, BAR_COLOR1,
                    ((v - BAR_COLOR1_STOP) * 255) / (BAR_COLOR2_STOP - BAR_COLOR1_STOP));

            /* ========== 计算频谱条的四边形顶点 ========== */
            uint32_t di = deg + deg_space;  // 结束角度

            // 计算外边缘点1（远端）
            int32_t x1_out = get_cos(di, v);
            poly[0].x = center.x + x1_out;
            poly[0].y = center.y + get_sin(di, v);

            // 计算内边缘点1（近端）
            int32_t x1_in = get_cos(di, r_in);
            poly[1].x = center.x + x1_in;
            poly[1].y = center.y + get_sin(di, r_in);

            di += DEG_STEP - deg_space * 2;  // 移动到下一个角度

            // 计算内边缘点2
            int32_t x2_in = get_cos(di, r_in);
            poly[2].x = center.x + x2_in;
            poly[2].y = center.y + get_sin(di, r_in);

            // 计算外边缘点2
            int32_t x2_out = get_cos(di, v);
            poly[3].x = center.x + x2_out;
            poly[3].y = center.y + get_sin(di, v);

            // 绘制右侧频谱条（上半部分）
            lv_draw_polygon(draw_ctx, &draw_dsc, poly, 4);

            // 绘制左侧频谱条（下半部分）- 通过镜像X坐标实现对称
            poly[0].x = center.x - x1_out;
            poly[1].x = center.x - x1_in;
            poly[2].x = center.x - x2_in;
            poly[3].x = center.x - x2_out;
            lv_draw_polygon(draw_ctx, &draw_dsc, poly, 4);
        }
    }
}

/**
 * @brief 频谱动画回调函数
 * @param a 动画对象
 * @param v 当前动画值
 *
 * 更新频谱动画状态并触发重绘
 */
static void spectrum_anim_cb(void * a, int32_t v)
{
    lv_obj_t * obj = a;

    // 如果处于开始动画阶段，只触发重绘
    if(start_anim) {
        lv_obj_invalidate(obj);
        return;
    }

    // 更新频谱索引并触发重绘
    spectrum_i = v;
    lv_obj_invalidate(obj);

    /* ========== 处理低音检测和动态效果 ========== */
    static uint32_t bass_cnt = 0;      // 低音计数
    static int32_t last_bass = -1000;  // 上次低音位置
    static int32_t dir = 1;            // 旋转方向

    // 检测低音（第一频带振幅较大时）
    if(spectrum[spectrum_i][0] > 12) {
        if(spectrum_i - last_bass > 5) {  // 避免连续检测
            bass_cnt++;
            last_bass = spectrum_i;
            if(bass_cnt >= 2) {  // 连续检测到两次低音
                bass_cnt = 0;
                spectrum_lane_ofs_start = spectrum_i;  // 重置频谱通道偏移
                bar_ofs++;                             // 增加频谱条偏移
            }
        }
    }

    // 根据低音状态调整旋转方向
    if(spectrum[spectrum_i][0] < 4) bar_rot += dir;

    // 根据频谱数据调整专辑图片缩放（模拟震动效果）
    lv_img_set_zoom(album_img_obj, LV_IMG_ZOOM_NONE + spectrum[spectrum_i][0]);
}

/**
 * @brief 开始动画回调函数
 * @param a 动画变量指针
 * @param v 当前动画值
 *
 * 更新开始动画的值并触发重绘
 */
static void start_anim_cb(void * a, int32_t v)
{
    lv_coord_t * av = a;
    *av = v;  // 更新动画值
    lv_obj_invalidate(spectrum_obj);  // 触发频谱重绘
}

/**
 * @brief 创建专辑图片对象
 * @param parent 父对象
 * @return 创建的专辑图片对象
 *
 * 根据当前歌曲ID创建对应的专辑封面图片
 */
static lv_obj_t * album_img_create(lv_obj_t * parent)
{
    // 声明专辑封面图像资源
    LV_IMG_DECLARE(img_lv_demo_music_cover_1);
    LV_IMG_DECLARE(img_lv_demo_music_cover_2);
    LV_IMG_DECLARE(img_lv_demo_music_cover_3);
    LV_IMG_DECLARE(img_lv_demo_music_cover_4);
    LV_IMG_DECLARE(img_lv_demo_music_cover_5);
    LV_IMG_DECLARE(img_lv_demo_music_cover_6);
    LV_IMG_DECLARE(img_lv_demo_music_cover_7);
    LV_IMG_DECLARE(img_lv_demo_music_cover_8);
    LV_IMG_DECLARE(img_lv_demo_music_cover_9);
    LV_IMG_DECLARE(img_lv_demo_music_cover_10);
    LV_IMG_DECLARE(img_lv_demo_music_cover_11);

    lv_obj_t * img;
    img = lv_img_create(parent);

    // 根据歌曲ID选择对应的专辑封面和频谱数据
    if(track_id%3 == 0){
        spectrum = spectrum_1;  // 使用第一首歌曲的频谱数据
        spectrum_len = sizeof(spectrum_1) / sizeof(spectrum_1[0]);
    }else if(track_id%3 == 1){
        spectrum = spectrum_2;  // 使用第二首歌曲的频谱数据
        spectrum_len = sizeof(spectrum_2) / sizeof(spectrum_2[0]);
    }else{
        spectrum = spectrum_3;  // 使用第三首歌曲的频谱数据
        spectrum_len = sizeof(spectrum_3) / sizeof(spectrum_3[0]);
    }

    if(track_id%11 == 0){
        lv_img_set_src(img, &img_lv_demo_music_cover_1);
    }else if(track_id%11 == 1){
        lv_img_set_src(img, &img_lv_demo_music_cover_2);
    }else if(track_id%11 == 2){
        lv_img_set_src(img, &img_lv_demo_music_cover_3);
    }else if(track_id%11 == 3){
        lv_img_set_src(img, &img_lv_demo_music_cover_4);
    }else if(track_id%11 == 4){
        lv_img_set_src(img, &img_lv_demo_music_cover_5);
    }else if(track_id%11 == 5){
        lv_img_set_src(img, &img_lv_demo_music_cover_6);
    }else if(track_id%11 == 6){
        lv_img_set_src(img, &img_lv_demo_music_cover_7);
    }else if(track_id%11 == 7){
        lv_img_set_src(img, &img_lv_demo_music_cover_8);
    }else if(track_id%11 == 8){
        lv_img_set_src(img, &img_lv_demo_music_cover_9);
    }else if(track_id%11 == 9){
        lv_img_set_src(img, &img_lv_demo_music_cover_10);
    }else{
        lv_img_set_src(img, &img_lv_demo_music_cover_11);
    }


    // 设置图片属性
    lv_img_set_antialias(img, false);  // 禁用抗锯齿以获得更清晰的边缘
    lv_obj_align(img, LV_ALIGN_CENTER, 0, 0);  // 居中对齐

    // 添加手势事件支持（左右滑动切换歌曲）
    lv_obj_add_event_cb(img, album_gesture_event_cb, LV_EVENT_GESTURE, NULL);
    lv_obj_clear_flag(img, LV_OBJ_FLAG_GESTURE_BUBBLE);  // 阻止手势事件冒泡
    lv_obj_add_flag(img, LV_OBJ_FLAG_CLICKABLE);         // 启用点击

    return img;
}

/**
 * @brief 专辑图片手势事件回调
 * @param e 事件对象
 *
 * 处理专辑图片上的左右滑动手势，用于切换歌曲
 */
static void album_gesture_event_cb(lv_event_t * e)
{
    lv_dir_t dir = lv_indev_get_gesture_dir(lv_indev_get_act());  // 获取手势方向
    if(dir == LV_DIR_LEFT) _lv_demo_music_album_next(true);   // 左滑：下一首
    if(dir == LV_DIR_RIGHT) _lv_demo_music_album_next(false); // 右滑：上一首
}

/**
 * @brief 播放/暂停按钮点击事件回调
 * @param e 事件对象
 *
 * 根据按钮状态切换播放和暂停
 */
static void play_event_click_cb(lv_event_t * e)
{
    lv_obj_t * obj = lv_event_get_target(e);
    if(lv_obj_has_state(obj, LV_STATE_CHECKED)) {
        _lv_demo_music_resume();  // 选中状态（暂停图标）：恢复播放
        mp3_resume_playback();
    } else {
        _lv_demo_music_pause();   // 未选中状态（播放图标）：暂停播放
        mp3_pause();
    }
}

/**
 * @brief 上一首按钮点击事件回调
 * @param e 事件对象
 */
static void prev_click_event_cb(lv_event_t * e)
{
    LV_UNUSED(e);
    _lv_demo_music_album_next(false);  // 切换到上一首
}

/**
 * @brief 下一首按钮点击事件回调
 * @param e 事件对象
 */
static void next_click_event_cb(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    if(code == LV_EVENT_CLICKED) {
        _lv_demo_music_album_next(true);  // 切换到下一首
    }
}

/**
 * @brief 定时器回调函数
 * @param t 定时器对象
 *
 * 每秒更新播放时间和进度条
 */
static void timer_cb(lv_timer_t * t)
{
    LV_UNUSED(t);
    time_act++;  // 增加当前时间

    // 更新时间显示标签（格式：分:秒）
    lv_label_set_text_fmt(time_obj, "%"LV_PRIu32":%02"LV_PRIu32, time_act / 60, time_act % 60);

    // 更新进度条位置
    lv_slider_set_value(slider_obj, time_act, LV_ANIM_ON);

    // 更新歌词显示（转换为毫秒）
    lv_demo_music_lyric_update_time(time_act * 1000);

    // 检查歌曲是否播放结束
    uint32_t track_length = _lv_demo_music_get_track_length(track_id);
    if (time_act >= track_length && track_length > 0) {
        _lv_demo_music_album_next(true);  // 切换到下一首
    }
}

/**
 * @brief 频谱动画结束回调
 * @param a 动画对象
 *
 * 当一首歌曲播放完成时自动切换到下一首
 */
static void spectrum_end_cb(lv_anim_t * a)
{
    LV_UNUSED(a);

    // 确保进度条显示完整
//    uint32_t total_time = _lv_demo_music_get_track_length(track_id);
//    lv_slider_set_value(slider_obj, total_time, LV_ANIM_ON);

    // 完全禁止自动切歌 - 注释掉运动歌单的切歌逻辑
    // extern bool lv_demo_music_is_sport_playlist_mode(void);
    // extern void lv_demo_music_play_next_sport_track(void);
    //
    // if (lv_demo_music_is_sport_playlist_mode()) {
    //     lv_demo_music_play_next_sport_track();
    // } else {
    //     // _lv_demo_music_album_next(true);
    // }

    // 频谱动画结束后只循环频谱动画，不切换歌曲
    spectrum_i = 0;
    lv_anim_t anim;
    lv_anim_init(&anim);
    lv_anim_set_values(&anim, 0, spectrum_len - 1);
    lv_anim_set_exec_cb(&anim, spectrum_anim_cb);
    lv_anim_set_var(&anim, spectrum_obj);
    lv_anim_set_time(&anim, (spectrum_len * 1000) / 30);
    lv_anim_set_ready_cb(&anim, spectrum_end_cb);
    lv_anim_start(&anim);
}


/**
 * @brief 停止开始动画的定时器回调
 * @param t 定时器对象
 *
 * 在指定时间后停止开始动画效果
 */
static void stop_start_anim(lv_timer_t * t)
{
    LV_UNUSED(t);
    start_anim = false;  // 禁用开始动画标志
    lv_obj_refresh_ext_draw_size(spectrum_obj);  // 刷新绘制大小
}

/**
 * @brief 进度条事件回调函数
 * @param e 事件对象
 *
 * 处理进度条的拖动事件，实现通过滑动进度条改变播放进度
 */
static void slider_event_cb(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);

    if(code == LV_EVENT_PRESSED) {
        // 开始拖动时暂停播放
        slider_dragging = true;
        _lv_demo_music_pause();
        //mp3_pause();这个地方不能暂停，暂停的话就无法获取歌曲信息，导致无法跳转
    }
    else if(code == LV_EVENT_RELEASED || code == LV_EVENT_PRESS_LOST) {
        // 结束拖动时根据新位置恢复播放
        slider_dragging = false;

        // 获取进度条的值（秒）
        int32_t new_time = lv_slider_get_value(slider_obj);

        printf(">>> 接收到跳转请求: %d 秒\n", new_time);

        seek_to_seconds(new_time);

        // 计算对应的频谱索引
        uint32_t total_time = _lv_demo_music_get_track_length(track_id);
        if(total_time > 0) {
            spectrum_i = (new_time * spectrum_len) / total_time;
            if(spectrum_i >= spectrum_len) spectrum_i = spectrum_len - 1;
        }

        // 更新时间显示
        time_act = new_time;
        lv_label_set_text_fmt(time_obj, "%"LV_PRIu32":%02"LV_PRIu32, time_act / 60, time_act % 60);

        // 从新位置恢复播放
        _lv_demo_music_resume();
        mp3_resume_playback();
    }
    else if(code == LV_EVENT_VALUE_CHANGED && slider_dragging) {
        // 拖动过程中实时更新时间显示
        int32_t new_time = lv_slider_get_value(slider_obj);
        lv_label_set_text_fmt(time_obj, "%"LV_PRIu32":%02"LV_PRIu32, new_time / 60, new_time % 60);

        // 实时更新频谱显示（可选，提供视觉反馈）
        uint32_t total_time = _lv_demo_music_get_track_length(track_id);
        if(total_time > 0) {
            uint32_t temp_spectrum_i = (new_time * spectrum_len) / total_time;
            if(temp_spectrum_i < spectrum_len) {
                // 临时更新频谱显示但不影响实际播放
                spectrum_i = temp_spectrum_i;
                lv_obj_invalidate(spectrum_obj);

                // 更新专辑图片缩放效果
                if(spectrum && spectrum_i < spectrum_len) {
                    lv_img_set_zoom(album_img_obj, LV_IMG_ZOOM_NONE + spectrum[spectrum_i][0]);
                }
            }
        }
    }
}

// 辅助函数：在选项字符串中查找文本的索引
static int find_option_index(const char* options, const char* target)
{
    if (!options || !target) return -1;

    const char* ptr = options;
    int index = 0;
    char buffer[64];

    while (*ptr) {
        // 找到下一个换行符或字符串结束
        const char* end = strchr(ptr, '\n');
        if (!end) end = ptr + strlen(ptr);

        // 提取当前选项
        int len = end - ptr;
        if (len >= (int)sizeof(buffer)) len = sizeof(buffer) - 1;
        strncpy(buffer, ptr, len);
        buffer[len] = '\0';

        // 比较是否匹配
        if (strcmp(buffer, target) == 0) {
            return index;
        }

        // 移动到下一个选项
        index++;
        ptr = (*end == '\n') ? end + 1 : end;
    }

    return -1;  // 未找到
}

/**
 * @brief 导入弹窗选项回调函数
 * @param e 事件对象
 */
static void import_popup_item_event_cb(lv_event_t * e)
{
    lv_obj_t * obj = lv_event_get_target(e);

    // 获取按钮文本
    lv_obj_t * label = lv_obj_get_child(obj, 0);
    const char * txt = lv_label_get_text(label);

    // 根据点击的选项执行相应操作
    if(strcmp(txt, "导入MP3与LRC") == 0) {
        int result = mp3_import_main(1);
        if(import_popup_bg) {
            lv_obj_del(import_popup_bg);
            import_popup_bg = NULL;
        }
    }
    else if(strcmp(txt, "导入MP3") == 0) {
        int result = mp3_import_main(0);
        if(import_popup_bg) {
            lv_obj_del(import_popup_bg);
            import_popup_bg = NULL;
        }
    }
}

/**
 * @brief 导入弹窗关闭事件回调
 * @param e 事件对象
 */
static void import_popup_close_event_cb(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    if(code == LV_EVENT_CLICKED) {
        if(import_popup_bg) {
            lv_obj_del(import_popup_bg);
            import_popup_bg = NULL;
        }
    }
}

/**
 * @brief 导入弹窗关闭事件回调（返回一级设置）
 * @param e 事件对象
 */
static void import_popup_close_event_cb_to_setting(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    if(code == LV_EVENT_CLICKED) {
        if(import_popup_bg) {
            lv_obj_del(import_popup_bg);
            import_popup_bg = NULL;
        }
        create_settings_popup(lv_scr_act());
    }
}


//=====第五部分结束============================================================================================================================//
